﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Security.Principal;
using System.Threading;

namespace Check_Printing_Solution
{
    public partial class PrintSelected : Form
    {
        PrintManager manager = new PrintManager();
        DataSet originalds = new DataSet();
        IntegratedForm mainform = new IntegratedForm();
        PrintFileEngine pe = new PrintFileEngine();

        private DataSet ToBePrinted { get; set; }
        private bool Stop { get; set; }

        public PrintSelected()
        {
            InitializeComponent();
        }

        public void MarkRow( string accountnumber, string accountholder )
        {
            foreach ( DataGridViewRow row in dataGridView1.Rows )
            {
                string rowaccnum = row.Cells[ 1 ].Value.ToString();
                string rowaccholder = row.Cells[ 5 ].Value.ToString();

                if ( rowaccnum == accountnumber && rowaccholder == accountholder )
                {
                    row.DefaultCellStyle.BackColor = Color.Yellow;
                }
            }
        }

        public PrintSelected( IntegratedForm form )
        {
            InitializeComponent();
            mainform = form;
            backgroundWorker1.DoWork += new DoWorkEventHandler( backgroundWorker1_DoWork );
        }

        public string FormatAccountNumber( string accountnumber )
        {
            if ( accountnumber.Length < 14 )
            {
                for ( int i = accountnumber.Length; i < 14; i++ )
                {
                    accountnumber = "0" + accountnumber;
                }
            }
            return accountnumber;
        }

        void backgroundWorker1_DoWork( object sender, DoWorkEventArgs e )
        {
            List<string> printdocs = new List<string>();

            foreach ( DataRow dr in ToBePrinted.Tables[ "Customers" ].Rows )
            {
                int CUSTOMER_NAME = 5;
                int LINE1 = 6;
                int LINE2 = 7;
                int LINE3 = 8;
                int ACCOUNT_NO = 1;
                int STYLE = 10;
                int NEXT_CHEQUE_NUMBER = 12;
                int PREFIX = 0;
                int TOTAL_BOOKS = 4;
                int TOTAL_LEAVES = 13;


                if ( !PrintRunner.StopPrint )
                {
                    try
                    {
                        pe = new PrintFileEngine( this );
                        Customer customer = new Customer();
                        customer.FirstName = dr[ CUSTOMER_NAME ].ToString();
                        customer.Line1 = dr[ LINE1 ].ToString();
                        customer.Line2 = dr[ LINE2 ].ToString();
                        customer.Line3 = dr[ LINE3 ].ToString();
                        customer.ChequeNumber = FormatAccountNumber( dr[ ACCOUNT_NO ].ToString() );

                        Bank bank = manager.GetBankByPrefix( dr[ PREFIX ].ToString() );

                        if ( bank == null )
                        {
                            MessageBox.Show( "Cannot find bank " + dr[ PREFIX ].ToString(), "Printing Error", MessageBoxButtons.OK, MessageBoxIcon.Error );
                        }

                        string style = dr[ STYLE ].ToString();
                        TemplateLayout template = manager.GetTemplateLayoutByStyle( style );

                        if ( template == null )
                        {
                            MessageBox.Show( "Print template does not exist. Please create under manage cheques.", "Printing Error", MessageBoxButtons.OK, MessageBoxIcon.Error );
                        }

                        string comment = "Printed from File: " + openFileDialog1.SafeFileName;
                        string nextchequenumber = dr[ NEXT_CHEQUE_NUMBER ].ToString();
                        if ( nextchequenumber == string.Empty || nextchequenumber == null )
                        {
                            nextchequenumber = "1";
                        }
                        string styleid = template.Id;

                        pe.InitiatePrint(
                            printDialog1.PrinterSettings.PrinterName,
                            customer,
                            bank,
                            style,
                            comment,
                            nextchequenumber,
                            styleid,
                            Convert.ToInt32( dr[ TOTAL_BOOKS ].ToString() ),
                            Convert.ToInt32( dr[ TOTAL_LEAVES ].ToString() ),
                            openFileDialog1.FileName,
                            chkIsReprint.Checked
                            );

                        printdocs.Add(
                            customer.FirstName + ", " +
                            customer.ChequeNumber + ", " +
                            style + "\r\n"
                             );
                    }
                    catch ( Exception ex )
                    {
                        manager.LogApplicationEvent( new ApplicationLog()
                        {
                            EventTime = DateTime.Now,
                            EventUser = WindowsIdentity.GetCurrent().Name.ToString(),
                            Event = "Printing File: " + ex.ToString()
                        } );
                        MessageBox.Show( ex.ToString(), "Input File Error.", MessageBoxButtons.OK, MessageBoxIcon.Error );
                    }
                }
            }
            mainform.SetLogs( printdocs );
        }

        private void rdoPrintOne_CheckedChanged( object sender, EventArgs e )
        {
            if ( rdoPrintOne.Checked )
            {
                txtPrintMultiple.ReadOnly = true;
                txtPrintFrom.ReadOnly = true;
                txtPrintTo.ReadOnly = true;
                txtPrintOne.ReadOnly = false;

                txtPrintFromStyle.ReadOnly = true;
                txtPrintMultipleStyle.ReadOnly = true;
                txtPrintToStyle.ReadOnly = true;
                txtPrintOneStyle.ReadOnly = false;
            }
        }

        private void rdoPrintMultiple_CheckedChanged( object sender, EventArgs e )
        {
            if ( rdoPrintMultiple.Checked )
            {
                txtPrintMultiple.ReadOnly = false;
                txtPrintFrom.ReadOnly = true;
                txtPrintTo.ReadOnly = true;
                txtPrintOne.ReadOnly = true;

                txtPrintFromStyle.ReadOnly = true;
                txtPrintMultipleStyle.ReadOnly = false;
                txtPrintToStyle.ReadOnly = true;
                txtPrintOneStyle.ReadOnly = true;
            }
        }

        private void rdoPrintRange_CheckedChanged( object sender, EventArgs e )
        {
            if ( rdoPrintRange.Checked )
            {
                txtPrintMultiple.ReadOnly = true;
                txtPrintFrom.ReadOnly = false;
                txtPrintTo.ReadOnly = false;
                txtPrintOne.ReadOnly = true;

                txtPrintFromStyle.ReadOnly = false;
                txtPrintMultipleStyle.ReadOnly = true;
                txtPrintToStyle.ReadOnly = false;
                txtPrintOneStyle.ReadOnly = true;
            }
        }

        private void btnPrint_Click( object sender, EventArgs e )
        {
            PrintRunner.StopPrint = false;
            bool passed = true;
            Stop = false;

            if ( txtFileName.Text == string.Empty )
            {
                passed = false;
            }

            if ( rdoPrintOne.Checked && txtPrintOne.Text == string.Empty || txtPrintOneStyle.Text == string.Empty )
            {
                passed = false;
            }

            if ( rdoPrintMultiple.Checked && lstMultipleCheques.Items.Count == 0 )
            {
                passed = false;
            }

            if ( rdoPrintRange.Checked && ( txtPrintFrom.Text == string.Empty || txtPrintTo.Text == string.Empty
                || txtPrintFromStyle.Text == string.Empty || txtPrintToStyle.Text == string.Empty ) )
            {
                passed = false;
            }

            if ( rdoPrintSelectedType.Checked )
            {
                passed = true;
            }

            if ( !passed )
            {
                MessageBox.Show( "Please select a file and fill out necessary information before printing.", "Printing Cancelled", MessageBoxButtons.OK, MessageBoxIcon.Error );
            }

            if ( passed )
            {
                string filename = txtFileName.Text;
                string connectionString = string.Format( "Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", filename );

                //Customer information
                OleDbDataAdapter adpater = new OleDbDataAdapter( "SELECT * FROM [Sheet1$]", connectionString );
                DataSet ds = new DataSet();
                adpater.Fill( ds, "Customers" );

                OleDbDataAdapter adpater2 = new OleDbDataAdapter( "SELECT * FROM [DATA Source$]", connectionString );
                adpater2.Fill( ds, "Banks" );

                ds = manager.CleanCustomers( ds );

                if ( rdoPrintOne.Checked )
                {
                    ds = PrintOne( ds, txtPrintOne.Text, txtPrintOneStyle.Text );
                }
                else if ( rdoPrintMultiple.Checked )
                {
                    PrintMultiple( ds, "" );
                }
                else if ( rdoPrintRange.Checked )
                {
                    ds = PrintRange( ds, txtPrintFrom.Text, txtPrintTo.Text, txtPrintFromStyle.Text, txtPrintToStyle.Text );
                }
                else if ( rdoPrintSelectedType.Checked )
                {
                    ds = PrintType( ds, cmbChequeTypes.Text );
                }

                ToBePrinted = ds;

                if ( printDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK )
                {
                    backgroundWorker1.RunWorkerAsync();
                }
            }
        }

        private DataSet PrintOne( DataSet ds, string accountnumber, string style )
        {
            for ( int i = 0; i < ds.Tables[ "Customers" ].Rows.Count; i++ )
            {
                if ( ds.Tables[ "Customers" ].Rows[ i ][ 1 ].ToString() != accountnumber )
                {
                    ds.Tables[ "Customers" ].Rows[ i ].Delete();

                }
                else
                {
                    if ( ds.Tables[ "Customers" ].Rows[ i ][ 10 ].ToString() != style )
                    {
                        ds.Tables[ "Customers" ].Rows[ i ].Delete();
                    }
                }
            }
            ds.Tables[ "Customers" ].AcceptChanges();

            return ds;
        }

        private void PrintMultiple( DataSet ds, string style )
        {

        }

        private DataSet PrintType( DataSet ds, string chequetype )
        {
            for ( int i = 0; i < ds.Tables[ "Customers" ].Rows.Count; i++ )
            {
                if ( ds.Tables[ "Customers" ].Rows[ i ][ 10 ].ToString() != chequetype )
                {
                    ds.Tables[ "Customers" ].Rows[ i ].Delete();
                }
            }
            ds.Tables[ "Customers" ].AcceptChanges();

            return ds;
        }

        private DataSet PrintRange( DataSet ds, string from, string to, string fromstyle, string tostyle )
        {
            bool started = false;
            bool finished = false;

            for ( int i = 0; i < ds.Tables[ "Customers" ].Rows.Count; i++ )
            {
                if ( started == false && finished == false )
                {
                    if ( ds.Tables[ "Customers" ].Rows[ i ][ 0 ].ToString() != from && ds.Tables[ "Customers" ].Rows[ i ][ 9 ].ToString() != fromstyle )
                    {
                        ds.Tables[ "Customers" ].Rows[ i ].Delete();
                    }
                }
                if ( started == true && finished == false )
                {
                    if ( ds.Tables[ "Customers" ].Rows[ i ][ 0 ].ToString() != to && ds.Tables[ "Customers" ].Rows[ i ][ 9 ].ToString() != tostyle )
                    {
                        finished = true;
                    }
                }
                if ( started == true && finished == true )
                {
                    ds.Tables[ "Customers" ].Rows[ i ].Delete();
                }
            }
            ds.Tables[ "Customers" ].AcceptChanges();

            return ds;
        }

        private void btnCancel_Click( object sender, EventArgs e )
        {
            this.Close();
        }

        private void MarkPerviousCompleted()
        {

        }

        private void btnBrowse_Click( object sender, EventArgs e )
        {
            if ( openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK )
            {
                txtFileName.Text = openFileDialog1.FileName;
                string filename = txtFileName.Text;
                string connectionString = string.Format( "Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", filename );

                //Customer information
                OleDbDataAdapter adapter = new OleDbDataAdapter( "SELECT * FROM [Sheet1$]", connectionString );
                DataSet ds = new DataSet();
                adapter.Fill( ds, "Customers" );
                adapter.Fill( originalds, "Customers" );
                List<string> types = new List<string>();

                foreach ( DataRow dr in ds.Tables[ "Customers" ].Rows )
                {
                    var result = from i in types
                                 where i == dr[ 10 ].ToString()
                                 select i;

                    if ( result.Count() == 0 )
                    {
                        if ( dr[ 10 ].ToString().Trim() != string.Empty )
                        {
                            types.Add( dr[ 10 ].ToString() );
                        }
                    }
                }

                foreach ( string type in types )
                {
                    cmbChequeTypes.Items.Add( type );
                }
                cmbChequeTypes.Text = cmbChequeTypes.Items[ 0 ].ToString();

                dataGridView1.DataSource = ds.Tables[ "Customers" ];
                dataGridView1.Columns[ 1 ].HeaderText = "Account Number";
                dataGridView1.Columns[ 2 ].HeaderText = "Branch";
                dataGridView1.Columns[ 4 ].HeaderText = "# Books";
                dataGridView1.Columns[ 5 ].HeaderText = "Account Holder";

                foreach ( DataGridViewRow row in dataGridView1.Rows )
                {
                    string rowaccnum = row.Cells[ 1 ].Value.ToString();
                    string rowaccholder = row.Cells[ 5 ].Value.ToString();
                    string rowchequetype = row.Cells[ 10 ].Value.ToString();

                    if ( rowaccnum.Trim() != string.Empty && rowaccnum.Trim() != string.Empty )
                    {
                        if ( manager.IsRecordInLog( rowaccnum, rowaccholder, filename, rowchequetype ) )
                        {
                            row.DefaultCellStyle.BackColor = Color.Yellow;
                        }
                    }
                }
            }
            else
            {
                MessageBox.Show( "No cheques have been sent to the printer", "Printing Cancelled", MessageBoxButtons.OK, MessageBoxIcon.Stop );
            }
        }

        private void btnAdd_Click( object sender, EventArgs e )
        {
            lstMultipleCheques.Items.Add( txtPrintMultiple.Text + "|" + txtPrintMultipleStyle.Text );
            txtPrintMultiple.Text = string.Empty;
            txtPrintMultipleStyle.Text = string.Empty;
        }

        private void btnRemove_Click( object sender, EventArgs e )
        {
            lstMultipleCheques.Items.RemoveAt( lstMultipleCheques.SelectedIndex );
        }

        private void cmbChequeTypes_SelectedIndexChanged( object sender, EventArgs e )
        {
            dataGridView1.DataSource = FilterDataset( cmbChequeTypes.Text ).Tables[ "Customers" ];
            dataGridView1.Columns[ 0 ].Visible = false;
            dataGridView1.Columns[ 3 ].Visible = false;
        }

        private DataSet FilterDataset( string chequetype )
        {
            string filename = txtFileName.Text;
            string connectionString = string.Format( "Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", filename );

            //Customer information
            OleDbDataAdapter adpater = new OleDbDataAdapter( "SELECT * FROM [Sheet1$]", connectionString );
            DataSet ds = new DataSet();
            adpater.Fill( ds, "Customers" );

            OleDbDataAdapter adpater2 = new OleDbDataAdapter( "SELECT * FROM [DATA Source$]", connectionString );
            adpater2.Fill( ds, "Banks" );

            for ( int i = 0; i < ds.Tables[ "Customers" ].Rows.Count; i++ )
            {
                if ( ds.Tables[ "Customers" ].Rows[ i ][ 10 ].ToString() != chequetype )
                {
                    ds.Tables[ "Customers" ].Rows[ i ].Delete();
                }
            }

            return ds;
        }

        private void btnCancelPrints_Click( object sender, EventArgs e )
        {
            PrintRunner.StopPrint = true;
            //Stop = true;
            backgroundWorker1.CancelAsync();
            backgroundWorker1.Dispose();
            MessageBox.Show( "All printing cancelled.", "Cancellation", MessageBoxButtons.OK, MessageBoxIcon.Stop );
        }

        private void dataGridView1_SelectionChanged( object sender, EventArgs e )
        {
            if ( dataGridView1.SelectedRows.Count > 0 )
            {
                txtPrintOne.Text = dataGridView1.SelectedRows[ 0 ].Cells[ 1 ].Value.ToString();
                txtPrintOneStyle.Text = dataGridView1.SelectedRows[ 0 ].Cells[ 10 ].Value.ToString();
            }
        }

        private void PrintSelected_Load( object sender, EventArgs e )
        {

        }
    }
}